package com.mikufufu.blog.config;

import com.mikufufu.blog.common.cache.serializer.FastJson2JsonRedisSerializer;
import com.mikufufu.blog.listener.BaseListener;
import com.mikufufu.blog.listener.ListenerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.util.Map;

/**
 * redis配置
 * 
 */
@Configuration
public class RedisConfig{

    @Autowired
    private ListenerFactory listenerFactory;

    /**
     * 配置RedisTemplate
     * <p>
     *     redisTemplate方法是一个@Bean方法，@Bean注解括号中的参数用于指定RedisTemplate的名称。
     *     用于创建一个{@link  RedisTemplate}对象并配置它。
     *     它接受一个{@link  RedisConnectionFactory}参数作为Redis连接工厂。
     *     在方法内部，它创建了一个{@link FastJson2JsonRedisSerializer}对象用于序列化和反序列化Redis的value值，
     *     并将其设置为RedisTemplate的值序列化器。
     *     同时，它还使用{@link  StringRedisSerializer}来序列化和反序列化Redis的key值和Hash的key值。
     *     最后，它调用afterPropertiesSet方法来初始化{@link  RedisTemplate}对象，并返回它。
     * </p>
     * @param connectionFactory Redis连接工厂
     * @return RedisTemplate对象
     */
    @Bean("redisTemplate")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        // 创建一个RedisTemplate对象
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 设置Redis连接工厂
        template.setConnectionFactory(connectionFactory);

        // 创建一个FastJson2JsonRedisSerializer对象，用于序列化和反序列化Redis的value值
        FastJson2JsonRedisSerializer<Object> serializer = new FastJson2JsonRedisSerializer<>(Object.class);

        // 使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(serializer);

        // Hash的key也采用StringRedisSerializer的序列化方式
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(serializer);

        // afterPropertiesSet方法来初始化RedisTemplate对象，并返回它
        template.afterPropertiesSet();
        return template;
    }

    /**
     * 配置Redis消息监听器容器
     * <p>
     *     RedisMessageListenerContainer是Spring Data Redis提供的一个消息监听器容器，
     *     它可以监听Redis的消息，并调用相应的消息处理方法来处理消息。
     *     在本方法中，我们创建了一个RedisMessageListenerContainer对象，并设置了Redis连接工厂。
     *     然后，我们遍历所有实现BaseListener接口的监听器，并添加到Redis消息监听器容器中。
     * <p>
     * @param connectionFactory Redis连接工厂
     * @return RedisMessageListenerContainer对象
     */
    @Bean
    public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);

        // 添加Redis消息监听器
//        container.addMessageListener((message, pattern) -> {
//            // 处理Redis消息
//            System.out.println("Received message: " + JSON.parseObject(message.getBody(), String.class));
//        }, new ChannelTopic("demoTopic"));

        // 获取所有实现BaseListener接口的监听器
        listenerFactory.setListeners(container);

        // 设置序列化对象
        container.setTopicSerializer(new StringRedisSerializer());
        return container;
    }
}
